package game.ouroboros.levels;

import framework.input.Pool.PoolObjectFactory;
import framework.maths.Vector2;
import game.ouroboros.enemy.Ahpuch;
import game.ouroboros.enemy.AirSkiper;
import game.ouroboros.enemy.ArmoredOgre;
import game.ouroboros.enemy.Boom;
import game.ouroboros.enemy.Chaman;
import game.ouroboros.enemy.DarkOgre;
import game.ouroboros.enemy.Dragon;
import game.ouroboros.enemy.EkChua;
import game.ouroboros.enemy.Enemy;
import game.ouroboros.enemy.FireArcher;
import game.ouroboros.enemy.FireOgre;
import game.ouroboros.enemy.IceArcher;
import game.ouroboros.enemy.Ixtab;
import game.ouroboros.enemy.NightMare;
import game.ouroboros.enemy.Ogre;
import game.ouroboros.enemy.Skiper;
import game.ouroboros.magic.MapPositions;
import game.ouroboros.magic.PoolSuperPowerfull;
import game.ouroboros.temp.GenericPersonagem;

import java.util.ArrayList;
import java.util.List;
import android.util.Log;

/**
 * Representa um Level
 */
public class Level {
	PoolSuperPowerfull<Skiper> skiper;
	PoolSuperPowerfull<AirSkiper> airSkiper;
	PoolSuperPowerfull<Ogre> ogre;
	PoolSuperPowerfull<FireOgre> fireOgre;
	PoolSuperPowerfull<DarkOgre> darkOgre;
	PoolSuperPowerfull<IceArcher> iceArcher;
	PoolSuperPowerfull<FireArcher> fireArcher;
	PoolSuperPowerfull<Chaman> chaman;
	PoolSuperPowerfull<Boom> boom;
	PoolSuperPowerfull<ArmoredOgre> armoredOgre;
	PoolSuperPowerfull<NightMare> nightmare;
	PoolSuperPowerfull<Dragon> dragon;
	PoolSuperPowerfull<EkChua> ekChua;
	PoolSuperPowerfull<Ixtab> ixtab;
	PoolSuperPowerfull<Ahpuch> ahpuch;
	private int level = 0;
	private int time;
	private static final float TIME_RESPAWN = 0.1f;
	Vector2 position;
	private MapPositions map;

	/**
	 * Posição do nascedouro
	 * 
	 * @param x
	 * @param y
	 */
	public Level(Vector2 positon, MapPositions map) {
		this.map = map;
		this.time = 0;

		inUseObjects = new ArrayList<Enemy>(200);

		PoolObjectFactory<Skiper> SKIPER = new PoolObjectFactory<Skiper>() {
			public Skiper createObject() {
				return new Skiper(0, 0);
			}
		};
		skiper = new PoolSuperPowerfull<Skiper>(SKIPER, 30);

		PoolObjectFactory<AirSkiper> AIRSKIPER = new PoolObjectFactory<AirSkiper>() {
			public AirSkiper createObject() {
				return new AirSkiper(0, 0);
			}
		};
		airSkiper = new PoolSuperPowerfull<AirSkiper>(AIRSKIPER, 30);

		PoolObjectFactory<Ogre> OGRE = new PoolObjectFactory<Ogre>() {
			public Ogre createObject() {
				return new Ogre(0, 0);
			}
		};
		ogre = new PoolSuperPowerfull<Ogre>(OGRE, 30);

		PoolObjectFactory<DarkOgre> DARKOGRE = new PoolObjectFactory<DarkOgre>() {
			public DarkOgre createObject() {
				return new DarkOgre(0, 0);
			}
		};
		darkOgre = new PoolSuperPowerfull<DarkOgre>(DARKOGRE, 30);

		PoolObjectFactory<FireOgre> FIREOGRE = new PoolObjectFactory<FireOgre>() {
			public FireOgre createObject() {
				return new FireOgre(0, 0);
			}
		};
		fireOgre = new PoolSuperPowerfull<FireOgre>(FIREOGRE, 30);

		PoolObjectFactory<ArmoredOgre> ARMOREDOGRE = new PoolObjectFactory<ArmoredOgre>() {
			public ArmoredOgre createObject() {
				return new ArmoredOgre(0, 0);
			}
		};
		armoredOgre = new PoolSuperPowerfull<ArmoredOgre>(ARMOREDOGRE, 30);

		PoolObjectFactory<FireArcher> FIREARCHER = new PoolObjectFactory<FireArcher>() {
			public FireArcher createObject() {
				return new FireArcher(0, 0);
			}
		};
		fireArcher = new PoolSuperPowerfull<FireArcher>(FIREARCHER, 20);

		PoolObjectFactory<IceArcher> ICEARCHER = new PoolObjectFactory<IceArcher>() {
			public IceArcher createObject() {
				return new IceArcher(0, 0);
			}
		};
		iceArcher = new PoolSuperPowerfull<IceArcher>(ICEARCHER, 20);

		PoolObjectFactory<Boom> BOOM = new PoolObjectFactory<Boom>() {
			public Boom createObject() {
				return new Boom(0, 0);
			}
		};
		boom = new PoolSuperPowerfull<Boom>(BOOM, 20);

		PoolObjectFactory<NightMare> NIGHTMARE = new PoolObjectFactory<NightMare>() {
			public NightMare createObject() {
				return new NightMare(0, 0);
			}
		};
		nightmare = new PoolSuperPowerfull<NightMare>(NIGHTMARE, 10);

		PoolObjectFactory<Chaman> CHAMAN = new PoolObjectFactory<Chaman>() {
			public Chaman createObject() {
				return new Chaman(0, 0);
			}
		};
		chaman = new PoolSuperPowerfull<Chaman>(CHAMAN, 10);

		PoolObjectFactory<Dragon> DRAGON = new PoolObjectFactory<Dragon>() {
			public Dragon createObject() {
				return new Dragon(0, 0);
			}
		};
		dragon = new PoolSuperPowerfull<Dragon>(DRAGON, 1);

		PoolObjectFactory<EkChua> EKCHUA = new PoolObjectFactory<EkChua>() {
			public EkChua createObject() {
				return new EkChua(0, 0);
			}
		};
		ekChua = new PoolSuperPowerfull<EkChua>(EKCHUA, 1);

		PoolObjectFactory<Ixtab> IXTAB = new PoolObjectFactory<Ixtab>() {
			public Ixtab createObject() {
				return new Ixtab(0, 0);
			}
		};
		ixtab = new PoolSuperPowerfull<Ixtab>(IXTAB, 1);

		PoolObjectFactory<Ahpuch> AHPUCH = new PoolObjectFactory<Ahpuch>() {
			public Ahpuch createObject() {
				return new Ahpuch(0, 0);
			}
		};
		ahpuch = new PoolSuperPowerfull<Ahpuch>(AHPUCH, 1);

		this.level = 0;
	}

	private int enems;
	private static final int MAX_ENEMIES_AT_SCREEN = 40;
	private int enemiesQuantAtLevel;
	private List<Enemy> inUseObjects;
	private int quantCreated;

	public boolean levelIsFinished(){
		return ((inUseObjects.size()==0 ) && quantCreated>=enemiesQuantAtLevel );
	}
	
	public void update(float deltatime) {
		time += deltatime;
		Log.v("<NIHNO>", "UPDATE");
		if (time > TIME_RESPAWN && enems <= MAX_ENEMIES_AT_SCREEN
				&& quantCreated <= enemiesQuantAtLevel)
			time = 0;
		switch (level) {
		case 1:
			inUseObjects.add(skiper.newObject());
			inUseObjects.add(ogre.newObject());
			quantCreated += 2;
			enems += 2;
			break;
		case 2:
			inUseObjects.add(airSkiper.newObject());
			inUseObjects.add(darkOgre.newObject());
			quantCreated += 2;
			enems += 2;
			break;
		case 3:
			inUseObjects.add(iceArcher.newObject());
			inUseObjects.add(ogre.newObject());
			inUseObjects.add(fireOgre.newObject());
			quantCreated += 3;
			enems += 3;
			break;
		case 4:
			inUseObjects.add(iceArcher.newObject());
			inUseObjects.add(fireArcher.newObject());
			inUseObjects.add(skiper.newObject());
			inUseObjects.add(chaman.newObject());
			quantCreated += 4;
			enems += 4;
			break;
		case 5:
			inUseObjects.add(armoredOgre.newObject());
			inUseObjects.add(darkOgre.newObject());
			inUseObjects.add(boom.newObject());
			inUseObjects.add(nightmare.newObject());
			quantCreated += 5;
			enems += 5;
			break;
		case 6:
			inUseObjects.add(dragon.newObject());
			inUseObjects.add(airSkiper.newObject());
			inUseObjects.add(boom.newObject());
			inUseObjects.add(armoredOgre.newObject());
			inUseObjects.add(ogre.newObject());
			inUseObjects.add(skiper.newObject());
			inUseObjects.add(ixtab.newObject());
			quantCreated += 7;
			enems += 7;
			break;
		case 7:
			inUseObjects.add(ekChua.newObject());
			inUseObjects.add(airSkiper.newObject());
			inUseObjects.add(armoredOgre.newObject());
			inUseObjects.add(nightmare.newObject());
			inUseObjects.add(boom.newObject());
			inUseObjects.add(chaman.newObject());
			inUseObjects.add(nightmare.newObject());
			inUseObjects.add(dragon.newObject());
			inUseObjects.add(ahpuch.newObject());
			quantCreated += 9;
			enems += 9;
			break;
		}

		updateAllAlive(deltatime);
	}


	
	public void updateAllAlive(float deltaTime) {
		Log.v("<NINHO>", "Inimigo Update's");
		
		int len = inUseObjects.size();

		for (int i = 0; i < len; i++) {
			Enemy p = inUseObjects.get(i);
			if (p.isAlive()) {
				Log.v("<ENEMY>", "At: "+p.position.x+ " "+p.position.y);
				p.update(deltaTime);
			} else {
				Log.v("<ENEMY>","MORTO" );
				inUseObjects.remove(i);
				if (p instanceof AirSkiper) {
					airSkiper.free((AirSkiper) p);
				} else if (p instanceof Ahpuch) {
					ahpuch.free((Ahpuch) p);
				} else if (p instanceof ArmoredOgre) {
					armoredOgre.free((ArmoredOgre) p);
				} else if (p instanceof Boom) {
					boom.free((Boom) p);
				} else if (p instanceof Chaman) {
					chaman.free((Chaman) p);
				} else if (p instanceof DarkOgre) {
					darkOgre.free((DarkOgre) p);
				} else if (p instanceof Dragon) {
					dragon.free((Dragon) p);
				} else if (p instanceof EkChua) {
					ekChua.free((EkChua) p);
				} else if (p instanceof FireArcher) {
					fireArcher.free((FireArcher) p);
				} else if (p instanceof FireOgre) {
					fireOgre.free((FireOgre) p);
				} else if (p instanceof IceArcher) {
					iceArcher.free((IceArcher) p);
				} else if (p instanceof Ixtab) {
					ixtab.free((Ixtab) p);
				} else if (p instanceof NightMare) {
					nightmare.free((NightMare) p);
				} else if (p instanceof Ogre) {
					ogre.free((Ogre) p);
				} else if (p instanceof Skiper) {
					skiper.free((Skiper) p);
				}
			}
		}
	}

	public List<Enemy> getAlivePersonagens() {
		return inUseObjects;
	}

	public void nextLevel() {
		level++;
		time = 0;
		quantCreated = 0;
		enemiesQuantAtLevel = level * 30;
	}
}